package com.bf.electroplating.service.compoent;

import com.bf.electroplating.config.HJ212Config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * HJ212客户端管理器
 * 用于演示和管理HJ212客户端连接
 */
@Slf4j
@Component
public class HJ212ClientManager {
    
    @Autowired
    private HJ212Config hj212Config;
    
    // 存储客户端连接
    private final ConcurrentHashMap<String, SocketChannel> clientConnections = new ConcurrentHashMap<>();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
    
    /**
     * 创建并连接客户端
     * 
     * @param clientId 客户端ID
     * @param host 服务器地址
     * @param port 服务器端口
     * @return 是否连接成功
     */
    public boolean createClient(String clientId, String host, int port) {
        try {
            SocketChannel socketChannel = SocketChannel.open();
            socketChannel.configureBlocking(true);
            socketChannel.connect(new InetSocketAddress(host, port));
            
            clientConnections.put(clientId, socketChannel);
            log.info("客户端 {} 连接成功: {}:{}", clientId, host, port);
            
            // 启动消息接收线程
            startMessageReceiver(clientId, socketChannel);
            
            return true;
        } catch (IOException e) {
            log.error("客户端 {} 连接失败: {}:{}", clientId, host, port, e);
            return false;
        }
    }
    
    /**
     * 启动消息接收线程
     */
    private void startMessageReceiver(String clientId, SocketChannel socketChannel) {
        scheduler.submit(() -> {
            try {
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                while (socketChannel.isConnected() && !socketChannel.socket().isClosed()) {
                    int bytesRead = socketChannel.read(buffer);
                    if (bytesRead > 0) {
                        buffer.flip();
                        byte[] data = new byte[bytesRead];
                        buffer.get(data);
                        String message = new String(data, StandardCharsets.UTF_8);
                        log.info("客户端 {} 收到消息: {}", clientId, message);
                    } else if (bytesRead == -1) {
                        log.info("客户端 {} 连接已断开", clientId);
                        break;
                    }
                    buffer.clear();
                }
            } catch (IOException e) {
                log.error("客户端 {} 消息接收异常", clientId, e);
            } finally {
                clientConnections.remove(clientId);
                try {
                    socketChannel.close();
                } catch (IOException e) {
                    log.error("关闭客户端 {} 连接失败", clientId, e);
                }
            }
        });
    }
    
    /**
     * 发送消息给客户端
     * 
     * @param clientId 客户端ID
     * @param message 消息内容
     * @return 是否发送成功
     */
    public boolean sendMessage(String clientId, String message) {
        SocketChannel socketChannel = clientConnections.get(clientId);
        if (socketChannel == null) {
            log.warn("客户端 {} 不存在", clientId);
            return false;
        }
        
        try {
            byte[] data = message.getBytes(StandardCharsets.UTF_8);
            ByteBuffer buffer = ByteBuffer.wrap(data);
            socketChannel.write(buffer);
            log.info("客户端 {} 发送消息: {}", clientId, message);
            return true;
        } catch (IOException e) {
            log.error("客户端 {} 发送消息失败", clientId, e);
            return false;
        }
    }
    
    /**
     * 断开客户端连接
     * 
     * @param clientId 客户端ID
     * @return 是否断开成功
     */
    public boolean disconnectClient(String clientId) {
        SocketChannel socketChannel = clientConnections.remove(clientId);
        if (socketChannel != null) {
            try {
                socketChannel.close();
                log.info("客户端 {} 已断开连接", clientId);
                return true;
            } catch (IOException e) {
                log.error("断开客户端 {} 连接失败", clientId, e);
            }
        }
        return false;
    }
    
    /**
     * 获取所有客户端连接
     * 
     * @return 客户端连接映射
     */
    public ConcurrentHashMap<String, SocketChannel> getClientConnections() {
        return new ConcurrentHashMap<>(clientConnections);
    }
    
    /**
     * 获取客户端数量
     * 
     * @return 客户端数量
     */
    public int getClientCount() {
        return clientConnections.size();
    }
    
    /**
     * 检查客户端是否连接
     * 
     * @param clientId 客户端ID
     * @return 是否连接
     */
    public boolean isClientConnected(String clientId) {
        return clientConnections.containsKey(clientId);
    }
    
    /**
     * 创建测试客户端
     * 
     * @param count 客户端数量
     * @return 创建的客户端数量
     */
    public int createTestClients(int count) {
        int successCount = 0;
        for (int i = 0; i < count; i++) {
            String clientId = "test_client_" + System.currentTimeMillis() + "_" + i;
            boolean success = createClient(clientId, hj212Config.getHost(), hj212Config.getPort());
            if (success) {
                successCount++;
            }
            
            // 避免同时创建太多连接
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            }
        }
        
        log.info("创建测试客户端完成，成功: {}/{}", successCount, count);
        return successCount;
    }
    
    /**
     * 发送测试数据包
     * 
     * @param clientId 客户端ID
     * @return 是否发送成功
     */
    public boolean sendTestPacket(String clientId) {
        String testPacket = "##0000ST=91;CN=9011;PW=123456;MN=00000000000000000000;Flag=5;CP=&&RtdInterval=30&&\r\n";
        return sendMessage(clientId, testPacket);
    }
    
    /**
     * 向所有客户端发送测试数据包
     * 
     * @return 成功发送的客户端数量
     */
    public int sendTestPacketToAll() {
        int successCount = 0;
        for (String clientId : clientConnections.keySet()) {
            if (sendTestPacket(clientId)) {
                successCount++;
            }
        }
        return successCount;
    }
    
    /**
     * 清理所有客户端连接
     */
    public void cleanup() {
        for (String clientId : clientConnections.keySet()) {
            disconnectClient(clientId);
        }
        log.info("已清理所有客户端连接");
    }
    
    /**
     * 关闭管理器
     */
    public void shutdown() {
        cleanup();
        scheduler.shutdown();
        try {
            if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
                scheduler.shutdownNow();
            }
        } catch (InterruptedException e) {
            scheduler.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
} 